package only.level5.railgun.ysartifactsimulation.utils;

import only.level5.railgun.ysartifactsimulation.Bean.ArtifactInfo;
import only.level5.railgun.ysartifactsimulation.artifact.ArtifactWord;
import only.level5.railgun.ysartifactsimulation.artifact.SubElement;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 40.92
 * 45.45
 * 13.64
 */
public class ArtifactUtils {
    public static List<double[]> FLOWER_LIST = new ArrayList<>(100);
    public static List<double[]> PLUME_LIST = new ArrayList<>(100);
    public static List<double[]> EON_LIST = new ArrayList<>(100);
    public static List<double[]> GOBLET_LIST = new ArrayList<>(100);
    public static List<double[]> CIRCLET_LIST = new ArrayList<>(100);

    public static void main(String[] args) {
        ThreadLocalRandom random = ThreadLocalRandom.current();
        float gobletRandom = random.nextFloat();
        System.out.println(gobletRandom);
        int i = random.nextInt(6);
        System.out.println(i);
    }

    public static void removeRubbish() {
        cleanList(FLOWER_LIST);
        cleanList(PLUME_LIST);
        cleanList(EON_LIST);
        cleanList(GOBLET_LIST);
        cleanList(CIRCLET_LIST);
    }

    private static void cleanList(List<double[]> artifactArray) {
        if (artifactArray.size() < 25){
            return;
        }

        int size = artifactArray.size();

        artifactArray.sort((a, b) -> (int) (a[22]-b[22]));
        double[] rubbish = artifactArray.get(0);
        double aDouble = rubbish[22];
        if (aDouble < 100 * size) { // 375
//            outputArtifactInfo(rubbish);
            artifactArray.remove(rubbish);
        }

    }

    public static DecimalFormat decimalFormat = new DecimalFormat("####.0");
    public static void outputArtifactInfo(double[] rubbish) {

        int mainType = (int) rubbish[23];
        String[] artifactInfo = new String[5];
        int j = 1;
        for (int i = 1; i < 19; i++) {
            double value = rubbish[i];
            String valStr;
            if (value < 1){
                valStr = decimalFormat.format(value*100)+"%";
            }else {
                valStr = Double.valueOf(value).toString();
            }
            if(i==mainType){

                artifactInfo[0] = transIdWords(i) + ": +"+ valStr;
            }else if(value > 0 ){
                artifactInfo[j] = transIdWords(i) + ": +"+ valStr;
                j++;
            }
        }
        for (String s : artifactInfo) {
            System.out.println(s);
        }
        System.out.printf("-------套装:%d ,位置：%d-------- \n",(int)rubbish[21],(int)rubbish[0]);
    }

    public static String transIdWords(int i) {
        return switch (i) {
            case 1 -> "攻击力";
            case 2 -> "生命值";
            case 3 -> "防御力";
            case 4 -> "攻击力%";
            case 5 -> "生命值%";
            case 6 -> "防御力%";
            case 7 -> "精通";
            case 8 -> "充能";
            case 9 -> "暴击率";
            case 10 -> "暴击伤害";
            case 11 -> "治疗加成";
            case 12 -> "物理伤害提升";
            case 13 -> "水元素伤害提升";
            case 14 -> "火元素伤害提升";
            case 15 -> "冰元素伤害提升";
            case 16 -> "岩元素伤害提升";
            case 17 -> "雷元素伤害提升";
            case 18 -> "风元素伤害提升";
            case 19 -> "草元素伤害提升";
            default -> "";
        };
    }

    public static ArtifactInfo createWords(boolean is4word, int mainType) {
        ArtifactInfo info = new ArtifactInfo();
        info.setMainType(mainType);
        int[] subTypeArray = new int[4];
        for (int i = 0; i < 4; ) {
            int subType = getSubType();
            if (!isOld(subTypeArray, subType) && subType != mainType) {
                subTypeArray[i] = subType;
                i++;
            }
        }
        info.setSub1Type(subTypeArray[0]);
        info.setSub2Type(subTypeArray[1]);
        info.setSub3Type(subTypeArray[2]);
        info.setSub4Type(subTypeArray[3]);

        byte[] upgradeRandom = new byte[is4word ? 5 : 4];
        ThreadLocalRandom random = ThreadLocalRandom.current();
        random.nextBytes(upgradeRandom);
        int v1up = 1;
        int v2up = 1;
        int v3up = 1;
        int v4up = 1;
        for (byte b : upgradeRandom) {
            if (b < -64) {
                v1up++;
            } else if (b < 0) {
                v2up++;
            } else if (b < 64) {
                v3up++;
            } else {
                v4up++;
            }
        }
        info.setSub1value(SubElement.getInstanceByCode(subTypeArray[0]).finalValue(v1up));
        info.setSub2value(SubElement.getInstanceByCode(subTypeArray[1]).finalValue(v2up));
        info.setSub3value(SubElement.getInstanceByCode(subTypeArray[2]).finalValue(v3up));
        info.setSub4value(SubElement.getInstanceByCode(subTypeArray[3]).finalValue(v4up));
        return info;
    }

    private static boolean isOld(int[] array, int type) {
        boolean old = false;
        for (int j : array) {
            if (j == type) {
                old = true;
                break;
            }
        }
        return old;
    }

    private static int getSubType() {
        ThreadLocalRandom random = ThreadLocalRandom.current();
        float sub1 = random.nextFloat() * 100;
        if (sub1 < 40.92) {
            int v = (int) (sub1 / 13.64);
            return switch (v) {
                case 0 -> 1;
                case 1 -> 2;
                case 2 -> 3;
                default -> -1;
            };
        } else if (sub1 >= 40.92 && sub1 < 86.37) {
            sub1 -= 40.92;
            int v = (int) (sub1 / 9.09);
            return switch (v) {
                case 0 -> 4;
                case 1 -> 5;
                case 2 -> 6;
                case 3 -> 7;
                case 4 -> 8;
                default -> -1;
            };
        } else {
            sub1 -= 86.37;
            int v = (int) (sub1 / 6.82);
            return switch (v) {
                case 0 -> 9;
                case 1 -> 10;
                default -> -1;
            };
        }
    }

    public static double[] createGoblet() {
        ThreadLocalRandom random = ThreadLocalRandom.current();
        float gobletRandom = random.nextFloat();
        int mainType = 0;
        if (gobletRandom < 0.2125) {
            mainType = 4;
        } else if (gobletRandom >= 0.2125 && gobletRandom < 0.425) {
            mainType = 5;
        } else if (gobletRandom >= 0.425 && gobletRandom < 0.625) {
            mainType = 6;
        } else if (gobletRandom >= 0.625 && gobletRandom < 0.65) {
            mainType = 7;
        } else if (gobletRandom >= 0.65) {
            mainType = random.nextInt(6) + 12;
        }

        return createMain(mainType);
    }

    public static double[] createCirclet() {
        ThreadLocalRandom random = ThreadLocalRandom.current();
        float circletRandom = random.nextFloat();
        int mainType = 0;
        if (circletRandom < 0.22) {
            mainType = 4;
        } else if (circletRandom >= 0.22 && circletRandom < 0.44) {
            mainType = 5;
        } else if (circletRandom >= 0.44 && circletRandom < 0.66) {
            mainType = 6;
        } else if (circletRandom >= 0.66 && circletRandom < 0.7) {
            mainType = 7;
        } else if (circletRandom >= 0.7 && circletRandom < 0.8) {
            mainType = 9;
        } else if (circletRandom >= 0.8 && circletRandom < 0.9) {
            mainType = 10;
        } else if (circletRandom >= 0.9) {
            mainType = 11;
        }

        return createMain(mainType);
    }

    public static double[] createEon() {
        ThreadLocalRandom random = ThreadLocalRandom.current();
        float eonRandom = random.nextFloat();
        int mainType = 0;
        if (eonRandom < 0.2668) {
            mainType = 5;
        } else if (eonRandom >= 0.2668 && eonRandom < 0.5334) {
            mainType = 4;
        } else if (eonRandom >= 0.5334 && eonRandom < 0.8) {
            mainType = 6;
        } else if (eonRandom >= 0.8 && eonRandom < 0.9) {
            mainType = 7;
        } else if (eonRandom >= 0.9) {
            mainType = 8;
        }
        return createMain(mainType);
    }

    public static double[] createMain(int mainType) {
        ThreadLocalRandom random = ThreadLocalRandom.current();
        int suitCode = random.nextFloat() >= 0.5 ? 0 : 1;
        boolean is4word = random.nextFloat() >= 0.8;
        ArtifactInfo artifactInfo = createWords(is4word, mainType);
        artifactInfo.setSuitCode(suitCode);

        double[] artifactInfoValues = transArtifact2Array(artifactInfo);
        artifactInfoValues[20] = suitCode;
        artifactInfoValues[23] = mainType;
        return artifactInfoValues;
    }

    public static double[] transArtifact2Array(ArtifactInfo artifactInfo) {
        double[] artifactTotal = new double[24]; // 0:slot ;1~19:words ;20:suit ;21:time;22:score;23:mainType
        int mainType = artifactInfo.getMainType();
        ArtifactWord main = ArtifactWord.getInstanceByCode(mainType);
        artifactTotal[main.getCode()] = main.getValue();

        ArtifactWord sub1 = ArtifactWord.getInstanceByCode(artifactInfo.getSub1Type());
        artifactTotal[sub1.getCode()] = artifactInfo.getSub1value();

        ArtifactWord sub2 = ArtifactWord.getInstanceByCode(artifactInfo.getSub2Type());
        artifactTotal[sub2.getCode()] = artifactInfo.getSub2value();

        ArtifactWord sub3 = ArtifactWord.getInstanceByCode(artifactInfo.getSub3Type());
        artifactTotal[sub3.getCode()] = artifactInfo.getSub3value();

        ArtifactWord sub4 = ArtifactWord.getInstanceByCode(artifactInfo.getSub4Type());
        artifactTotal[sub4.getCode()] = artifactInfo.getSub4value();

        return artifactTotal;
    }

    public static double[] singleArtifact(int time) {
        ThreadLocalRandom random = ThreadLocalRandom.current();
        int slot = random.nextInt(5);
        double[] artifactInfo;

        if (slot == 0) {
            artifactInfo = createMain(2);
            Hutao.calcArtifactScore(artifactInfo);
            FLOWER_LIST.add(artifactInfo);
        } else if (slot == 1) {
            artifactInfo = createMain(1);
            Hutao.calcArtifactScore(artifactInfo);
            PLUME_LIST.add(artifactInfo);
        } else if (slot == 2) {
            artifactInfo = createEon();
            Hutao.calcArtifactScore(artifactInfo);
            EON_LIST.add(artifactInfo);
        } else if (slot == 3) {
            artifactInfo = createGoblet();
            Hutao.calcArtifactScore(artifactInfo);
            GOBLET_LIST.add(artifactInfo);
        } else {
            artifactInfo = createCirclet();
            Hutao.calcArtifactScore(artifactInfo);
            CIRCLET_LIST.add(artifactInfo);
        }

        artifactInfo[0] = slot;
        artifactInfo[21] = time;
        return artifactInfo;
    }
}
